package com.ddwl.user.controller;

import com.ddwl.common.annotation.Auth;
import com.ddwl.common.annotation.Limit;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.LimitType;
import com.ddwl.common.constant.LimitWay;
import com.ddwl.common.controller.BaseController;
import com.ddwl.common.exception.IllegalException;
import com.ddwl.common.util.HttpUtil;
import com.ddwl.schema.bo.gate.RegionBo;
import com.ddwl.schema.bo.user.*;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.user.*;
import com.ddwl.user.service.LoginService;
import com.ddwl.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map;
import java.util.Optional;

/**
 * @author Fu Zhaohui
 * @version 1.0.0
 * @date 2019/8/19 17:00
 */
@Api(tags = "登录服务")
@RestController
@RequiredArgsConstructor
public class LoginController extends BaseController {

    private final LoginService loginService;
    private final UserService userService;
    private final HttpServletRequest request;

    @PostMapping("/valid")
    @Auth
    @ApiOperation("校验Token是否有效")
    public RestVo<Boolean> valid() {
        return RestVo.ok();
    }

    @PostMapping("/login")
    @Auth(required = false)
    @ApiOperation("用户登录")
    public RestVo<LoginVo> login(@Valid @RequestBody LoginBo bo) {
        Map<String, String> authMap = getAuthMap();
        bo.setDk(authMap.get("dk"));
        bo.setProduct(authMap.get("pk"));
        bo.setIp(HttpUtil.getIp(request));
        bo.setUserAgent(request.getHeader("User-Agent"));
        return RestVo.ok(loginService.login(bo));
    }

    @PostMapping("/appLogin")
    @Auth(required = false)
    @ApiOperation("APP用户登录")
    public RestVo<LoginVo> login(@Valid @RequestBody AppLoginBo bo) {
        Map<String, String> authMap = getAuthMap();
        bo.setDk(authMap.get("dk"));
        bo.setProduct(authMap.get("pk"));
        bo.setIp(HttpUtil.getIp(request));
        bo.setUserAgent(request.getHeader("User-Agent"));
        return RestVo.ok(loginService.appLogin(bo));
    }


    @PostMapping("/logout")
    @Auth
    @ApiOperation("用户登出")
    public RestVo logout(HttpServletRequest request) {
        loginService.logout(request.getHeader("pk"), getUserId());
        return RestVo.ok();
    }

    @PostMapping("/check1.1")
    @Auth(required = false)
    @ApiOperation("检查手机号码是否注册，设置过密码")
    public RestVo<CheckMobileVo> checkMobile(@RequestParam String mobile) {
        return RestVo.ok(userService.checkMobile(mobile));
    }

    @PostMapping("/check")
    @Auth(required = false)
    @ApiOperation("检查手机号码")
    public RestVo<Boolean> check(@RequestParam String mobile) {
        return RestVo.ok(userService.check(mobile));
    }

    @PostMapping("/checkOpenId")
    @Auth(required = false)
    @ApiOperation("检查微信是否注册")
    public RestVo<Boolean> checkOpenId(@RequestParam String openId) {
        return RestVo.ok(userService.openIdIsRegister(openId));
    }

    /**
     * 微信用户注册和登录
     *
     * @param bo
     * @return
     */
    @PostMapping("/auth")
    @Auth(required = false)
    @ApiOperation("通用认证")
    public RestVo<LoginVo> auth(@Valid @RequestBody AuthBo bo) {
        Map<String, String> authMap = getAuthMap();
        bo.setDk(authMap.get("dk"));
        bo.setProduct(authMap.get("pk"));
        bo.setIp(HttpUtil.getIp(request));
        bo.setOpenId(Optional.ofNullable(bo.getOpenId()).orElse(bo.getDk()));
        bo.setUserAgent(request.getHeader("User-Agent"));
        IllegalException.isTrue(BaseEnum.ProductEnum.WBM.getName().equals(getProduct()));
        return RestVo.ok(loginService.auth(bo));
    }

    @PostMapping("/reg")
    @Auth(required = false)
    @ApiOperation("会员注册")
    public RestVo<UserVo> reg(@Valid @RequestBody RegisterBo bo) {
        Map<String, String> authMap = getAuthMap();
        bo.setDk(authMap.get("dk"));
        bo.setProduct(authMap.get("pk"));
        bo.setChannel(authMap.get("channel"));
        bo.setIp(HttpUtil.getIp(request));
        bo.setUserAgent(request.getHeader("User-Agent"));
        return RestVo.ok(userService.reg(bo));
    }

    @PostMapping("/wxMobileReg")
    @Auth(required = false)
    @ApiOperation("直接获取微信绑定手机号注册")
    public RestVo<UserVo> wxMobileReg(@Valid @RequestBody WxMobileRegisterBo bo) {
        Map<String, String> authMap = getAuthMap();
        bo.setDk(authMap.get("dk"));
        bo.setProduct(authMap.get("pk"));
        bo.setChannel(authMap.get("channel"));
        return RestVo.ok(userService.wxMobileReg(bo));
    }

    @PostMapping("/sentSms")
    @Auth(required = false)
    @ApiOperation("获取短信验证码")
    @Limit(count = 10, limitWay = LimitWay.DB, limitType = LimitType.DK, errMsg = "当前设备获取验证码达到上限")
    public RestVo<SentSmsVo> sentSmsCode(@Valid @RequestBody SentSmsBo sentSmsBo) {
        sentSmsBo.setProduct(getAuthMap().get("pk"));
        return RestVo.ok(userService.sendSMSCaptcha(sentSmsBo));
    }

    @PostMapping("/resetToken")
    @Auth(required = false)
    @ApiOperation("获取重置密码token")
    public RestVo<String> resetCode(@RequestParam("mobile") String mobile, @RequestParam("smsCode") String smsCode) {
        return RestVo.ok(userService.getRestKey(mobile, smsCode));
    }

    @PostMapping("/changedPwd")
    @Auth(product = BaseEnum.ProductEnum.CONSOLE)
    @ApiOperation("管理后台修改密码")
    public RestVo<UserVo> changedPwd(@Valid @RequestBody PwdBo bo) {
        bo.setUserId(getUserId());
        loginService.changePwd(bo);
        return RestVo.ok();
    }

    @PostMapping("/resetPwd")
    @Auth(required = false)
    @ApiOperation("重置密码")
    public RestVo<UserVo> changePwd(@Valid @RequestBody ResetPwdBo bo) {
        bo.setProduct(getAuthMap().get("pk"));
        userService.resetPwd(bo);
        return RestVo.ok();
    }

    @PostMapping("/regionInviteCode")
    @Auth(required = false)
    @ApiOperation("获取区域邀请码")
    public RestVo<InviteCodeVo> regionInviteCode(@RequestBody RegionBo regionBo) {
        return RestVo.ok(userService.getInviteCodeByRegion(regionBo));
    }

    @PostMapping("/oauth/info")
    @ApiOperation("登录信息")
    @Auth(required = false, product = BaseEnum.ProductEnum.WBM_OFFICE)
    public RestVo<OAuthVo> oauthInfo(@RequestParam String appId, @RequestParam String pk, @RequestParam String code, @RequestParam String uuid) {
        return RestVo.ok(loginService.oauthInfo(appId, pk, code, uuid));
    }

    @PostMapping("/oauth/submit")
    @ApiOperation("登录信息确认登录")
    @Auth(required = false, product = BaseEnum.ProductEnum.WBM_OFFICE)
    public RestVo oauthSubmit(@RequestParam String uuid, @RequestParam String openId) {
        loginService.oauthSubmit(uuid, openId);
        return RestVo.ok();
    }

    @GetMapping("/oauth/check")
    @ApiOperation("检查扫码登录状态")
    @Auth(required = false, product = BaseEnum.ProductEnum.SHOP_CONSOLE)
    public RestVo<LoginVo> oauthCheck(@RequestParam String uuid) {
        return RestVo.ok(loginService.oauthCheck(uuid));
    }
}
